package edu.unc.ils.memai.extract;

import java.util.Arrays;


import java.util.List;

import maui.stemmers.Stemmer;

public class Utils 
{
    
    /** 
     * Generates the preudo phrase from a string.
     * A pseudo phrase is a version of a phrase
     * that only contains non-stopwords,
     * which are stemmed and sorted into alphabetical order. 
     */
    public static String normalizePhrase(String phrase, Stemmer stemmer, 
            List<String> stopwords, boolean toLowerCase, boolean reorder) 
    {
        
        if (toLowerCase) {
            phrase = phrase.toLowerCase();
        }
        
        if (toLowerCase) {
            phrase = phrase.toLowerCase();
        }
        StringBuffer result = new StringBuffer();
        char prev = ' ';
        int i = 0;
        while (i < phrase.length()) {
            char c = phrase.charAt(i);
            
            // we ignore everything after the "/" symbol and everything in brackets
            // e.g. Monocytes/*immunology/microbiology -> monocytes
            // e.g. Vanilla (Spice) -> vanilla
            if (c == '/' || c == '(') 
                break;
            
            if (c == '-' ||  c == '&' || c == '.' || c == '.') 
                c = ' ';
                
            if (c == '*' || c == ':') {
                prev = c;
                i++;
                continue;
            }
            
            if (c != ' ' || prev != ' ')
                result.append(c);
            
            prev = c;
            i++;
        }

    
        phrase = result.toString().trim();
        
        if (reorder || stopwords != null || stemmer != null) {
            phrase = pseudoPhrase(phrase, stemmer, stopwords, reorder);
        } 
        if (phrase.equals("")) {
            // to prevent cases where the term is a stop word (e.g. Back).
            return result.toString(); 
        } else {
            return phrase;
        }
    }
    
    /** 
     * Generates the preudo phrase from a string.
     * A pseudo phrase is a version of a phrase
     * that only contains non-stopwords,
     * which are stemmed and sorted into alphabetical order. 
     */
    public static String pseudoPhrase(String str, Stemmer stemmer, List<String> stopwords, boolean reorder) {
        String result = "";
        String[] words = str.split(" ");
        if (reorder) {
            Arrays.sort(words);
        }
        for (String word : words) {

            if (stopwords != null) {
                if (stopwords.contains(word)) {
                    continue;
                }
            }

            int apostr = word.indexOf('\'');
            if (apostr != -1) {
                word = word.substring(0, apostr);
            }

            if (stemmer != null) {
                word = stemmer.stem(word);
            }
            result += word + " ";
        }
        return result.trim();
    }

    
    /**
     * Generates the preudo phrase from a string. A pseudo phrase is a version
     * of a phrase that only contains non-stopwords, which are stemmed and
     * sorted into alphabetical order.
     */
    /*
    public String pseudoPhraseKEA(Stemmer stemmer, List<String> stopwords, String str) {
        // System.err.print(str + "\t");
        String[] pseudophrase;
        String[] words;
        String str_nostop;
        String stemmed;

        str = str.toLowerCase();

        // This is often the case with Mesh Terms,
        // where a term is accompanied by another specifying term
        // e.g. Monocytes/*immunology/microbiology
        // we ignore everything after the "/" symbol.
        if (str.matches(".+?/.+?")) {
            String[] elements = str.split("/");
            str = elements[0];
        }

        // removes scop notes in brackets
        // should be replaced with a cleaner solution
        if (str.matches(".+?\\(.+?")) {
            String[] elements = str.split("\\(");
            str = elements[0];
        }
        //          if (str.matches(".+?\\'.+?")) {
        //                  String[] elements = str.split("\\'");
        //                  str = elements[1];
        //          }

        // Remove some non-alphanumeric characters

        // str = str.replace('/', ' ');
        str = str.replace('-', ' ');
        str = str.replace('&', ' ');

        str = str.replaceAll("\\*", "");
        str = str.replaceAll("\\, ", " ");
        str = str.replaceAll("\\. ", " ");
        str = str.replaceAll("\\:", "");

        str = str.trim();

        // Stem string
        words = str.split(" ");
        str_nostop = "";
        for (int i = 0; i < words.length; i++) {
            if (!stopwords.contains(words[i])) {
                if (str_nostop.equals("")) {
                    str_nostop = words[i];
                } else {
                    str_nostop = str_nostop + " " + words[i];
                }
            }
        }
        stemmed = stemmer.stem(str_nostop);

        // System.err.println(stemmed + "\t" + str_nostop + "\t"+ str);
        pseudophrase = sort(stemmed.split(" "));
        // System.err.println(join(pseudophrase));
        return join(pseudophrase);
        
    }
    */

    /**
     * Joins an array of strings to a single string.
     */
    /*

    private static String join(String[] str) {
        String result = "";
        for (int i = 0; i < str.length; i++) {
            if (result != "") {
                result = result + " " + str[i];
            } else {
                result = str[i];
            }
        }
        return result;
    }

    public static void swap(int loc1, int loc2, String[] a) {
        String temp = a[loc1];
        a[loc1] = a[loc2];
        a[loc2] = temp;
    } // end swap
    */

    /**
     * Sorts an array of Strings into alphabetic order
     *
     */
    /*
    public static String[] sort(String[] a) {

        // rename firstAt to reflect new role in alphabetic sorting
        int i, j, firstAt;

        for (i = 0; i < a.length - 1; i++) {
            firstAt = i;
            for (j = i + 1; j < a.length; j++) {
                // modify to preserve ordering of a String that starts with
                // upper case preceding the otherwise identical String that
                // has only lower case letters
                if (a[j].toUpperCase().compareTo(a[firstAt].toUpperCase()) < 0) {
                    // reset firstAt
                    firstAt = j;
                }
                // if identical when converted to all same case
                if (a[j].toUpperCase().compareTo(a[firstAt].toUpperCase()) == 0) {
                    // but a[j] precedes when not converted
                    if (a[j].compareTo(a[firstAt]) < 0) {
                        // reset firstAt
                        firstAt = j;
                    }
                }
            }
            if (firstAt != i) {
                swap(i, firstAt, a);
            }
        }
        return a;
    } // end method selectionSort
    */
}
